package com.saop.core.aspectj;

import com.saop.annotation.AopDialogBefore;
import com.saop.annotation.enums.DialogType;
import com.saop.core.api.DialogListener;
import com.saop.core.api.DialogParameter;
import com.saop.core.api.DialogParameterCallback;
import com.saop.core.utils.DialogUtils;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class DialogBeforeAspectJ {

    @Pointcut("execution(@com.saop.annotation.AopDialogBefore !synthetic *.new(..))")
    public void constructor() {
    }  //构造方法切入点


    @Pointcut("execution(@com.saop.annotation.AopDialogBefore !synthetic void *(..))")
    public void method() {
    }  //方法切入点

    @Around("( method() || constructor() ) && @annotation(dialog)")
    public void syncDialogAroundJoinPoint(ProceedingJoinPoint joinPoint, AopDialogBefore dialog) {
        // 获取方法中是否有DialogCallback回调
        DialogListener callback = null;
        for (Object arg : joinPoint.getArgs()) {
            if (arg instanceof DialogListener) {
                callback = (DialogListener) arg;
                break;
            }
        }
        // 先进行dialog显示 , 判断为sure 才进行执行方法体内容 , 最后进行选择回调
        DialogListener finalCallback = callback;
        DialogUtils
                .dialog()
                .setParameter(new DialogParameterCallback() {
                    @Override
                    public void reset(DialogParameter parameters) {
                        parameters.setTitle(dialog.title());
                        parameters.setMessage(dialog.message());
                        parameters.setPositive(dialog.positive());
                        parameters.setNegative(dialog.negative());
                        parameters.setNeutral(dialog.neutral());
                        parameters.setTouchOutSideCancel(dialog.touchOutSideCancel());
                    }
                })
                .callback(new DialogListener() {
                    @Override
                    public boolean isShow(DialogParameter parameters, Object result) {
                        if (finalCallback != null) {
                            return finalCallback.isShow(parameters, result);
                        }
                        return true;
                    }

                    @Override
                    public void onPositive(String positive) {
                        if (dialog.type() == DialogType.Positive) {
                            try {
                                joinPoint.proceed();
                            } catch (Throwable throwable) {
                                throwable.printStackTrace();
                            }
                        }
                        if (finalCallback != null) {
                            finalCallback.onPositive(positive);
                        }
                    }

                    @Override
                    public void onNegative(String negative) {
                        if (dialog.type() == DialogType.Negative) {
                            try {
                                joinPoint.proceed();
                            } catch (Throwable throwable) {
                                throwable.printStackTrace();
                            }
                        }
                        if (finalCallback != null) {
                            finalCallback.onNegative(negative);
                        }
                    }

                    @Override
                    public void onNeutral(String neutral) {
                        if (dialog.type() == DialogType.Neutral) {
                            try {
                                joinPoint.proceed();
                            } catch (Throwable throwable) {
                                throwable.printStackTrace();
                            }
                        }
                        if (finalCallback != null) {
                            finalCallback.onNeutral(neutral);
                        }
                    }

                    @Override
                    public void onCancel() {
                        if (finalCallback != null) {
                            finalCallback.onCancel();
                        }
                    }
                }).show();
    }
}
